home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / utils / rawrite.c < prev    next >
C/C++ Source or Header  |  1994-04-10  |  5KB  |  183 lines

  1. /*
  2.  rawrite.c    Write a binary image to a 360K diskette.
  3.         By Mark Becker
  4.  
  5.  Usage:
  6.     MS-DOS prompt> RAWRITE
  7.  
  8.     And follow the prompts.
  9.  
  10. History
  11. -------
  12.  
  13.   1.0    -    Initial release
  14.   1.1    -    Beta test (fixing bugs)                4/5/91
  15.           Some BIOS's don't like full-track writes.
  16.   1.101    -    Last beta release.                4/8/91
  17.           Fixed BIOS full-track write by only
  18.         writing 3 sectors at a time.
  19.   1.2    -    Final code and documentation clean-ups.        4/9/91
  20. */
  21. #include <alloc.h>
  22. #include <bios.h>
  23. #include <ctype.h>
  24. #include <dir.h>
  25. #include <dos.h>
  26. #include <io.h>
  27. #include <fcntl.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30.  
  31. #define FALSE    0
  32. #define TRUE    (!FALSE)
  33.  
  34. #define SECTORSIZE    512
  35.  
  36. #define    RESET    0
  37. #define    LAST    1
  38. #define    READ    2
  39. #define    WRITE    3
  40. #define    VERIFY    4
  41. #define    FORMAT    5
  42.  
  43. int    done;
  44.  
  45. /*
  46.  Catch ^C and ^Break.
  47. */
  48. int    handler(void)
  49. {
  50.   done = TRUE;
  51.   return(0);
  52. }
  53. void msg(char (*s))
  54. {
  55.     fprintf(stderr, "%s\n", s);
  56.     _exit(1);
  57. }
  58. /*
  59.  Identify the error code with a real error message.
  60. */
  61. void Error(int (status))
  62. {
  63.   switch (status) {
  64.     case 0x00:    msg("Operation Successful");                break;
  65.     case 0x01:    msg("Bad command");                    break;
  66.     case 0x02:    msg("Address mark not found");                break;
  67.     case 0x03:    msg("Attempt to write on write-protected disk");    break;
  68.     case 0x04:    msg("Sector not found");                break;
  69.     case 0x05:    msg("Reset failed (hard disk)");            break;
  70.     case 0x06:    msg("Disk changed since last operation");        break;
  71.     case 0x07:    msg("Drive parameter activity failed");            break;
  72.     case 0x08:    msg("DMA overrun");                    break;
  73.     case 0x09:    msg("Attempt to DMA across 64K boundary");        break;
  74.     case 0x0A:    msg("Bad sector detected");                break;
  75.     case 0x0B:    msg("Bad track detected");                break;
  76.     case 0x0C:    msg("Unsupported track");                break;
  77.     case 0x10:    msg("Bad CRC/ECC on disk read");            break;
  78.     case 0x11:    msg("CRC/ECC corrected data error");            break;
  79.     case 0x20:    msg("Controller has failed");                break;
  80.     case 0x40:    msg("Seek operation failed");                break;
  81.     case 0x80:    msg("Attachment failed to respond");            break;
  82.     case 0xAA:    msg("Drive not ready (hard disk only");            break;
  83.     case 0xBB:    msg("Undefined error occurred (hard disk only)");    break;
  84.     case 0xCC:    msg("Write fault occurred");                break;
  85.     case 0xE0:    msg("Status error");                    break;
  86.     case 0xFF:    msg("Sense operation failed");                break;
  87.   }
  88.   _exit(1);
  89. }
  90.  
  91. /*
  92.  Identify what kind of diskette is installed in the specified drive.
  93.  Return the number of sectors per track assumed as follows:
  94.  9    -    360 K and 720 K 5.25".
  95. 15    -    1.2 M HD    5.25".
  96. 18    -    1.44 M        3.5".
  97. */
  98. int nsects(int (drive))
  99. {
  100.   static    int    nsect[] = {18, 15, 9};
  101.  
  102.   char    *buffer;
  103.   int    i, status;
  104. /*
  105.  Read sector 1, head 0, track 0 to get the BIOS running.
  106. */
  107.   buffer = (char *)malloc(SECTORSIZE);
  108.   biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
  109.   status = biosdisk(READ, drive, 0, 10, 1, 1, buffer);
  110.   if (status == 0x06)            /* Door signal change?    */
  111.   status = biosdisk(READ, drive, 0, 0, 1, 1, buffer);
  112.  
  113.   for (i=0; i < sizeof(nsect)/sizeof(int); ++i) {
  114.     biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
  115.     status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
  116.     if (status == 0x06)
  117.       status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
  118.       if (status == 0x00) break;
  119.     }
  120.     if (i == sizeof(nsect)/sizeof(int)) {
  121.       msg("Can't figure out how many sectors/track for this diskette.");
  122.     }
  123.     free(buffer);
  124.     return(nsect[i]);
  125. }
  126.  
  127. void main(void)
  128. {
  129.   char     fname[MAXPATH];
  130.   char    *buffer, *pbuf;
  131.   int     count, fdin, drive, head, track, status, spt, buflength, ns;
  132.  
  133.   puts("RaWrite 1.2 - Write disk file to raw floppy diskette\n");
  134.   ctrlbrk(handler);
  135.   printf("Enter source file name: ");
  136.   scanf("%s", fname);
  137.   _fmode = O_BINARY;
  138.   if ((fdin = open(fname, O_RDONLY)) <= 0) {
  139.      perror(fname);
  140.      exit(1);
  141.   }
  142.  
  143.   printf("Enter destination drive: ");
  144.   scanf("%s", fname);
  145.   drive = fname[0];
  146.   drive = (islower(drive) ? toupper(drive) : drive) - 'A';
  147.   printf("Please insert a formatted diskette into ");
  148.   printf("drive %c: and press -ENTER- :", drive + 'A');
  149.   while (bioskey(1) == 0) ;                /* Wait...    */
  150.   if ((bioskey(0) & 0x7F) == 3) exit(1);        /* Check for ^C    */
  151.   putchar('\n');
  152.   done = FALSE;
  153. /*
  154.  * Determine number of sectors per track and allocate buffers.
  155.  */
  156.   spt = nsects(drive);
  157.   buflength = spt * SECTORSIZE;
  158.   buffer = (char *)malloc(buflength);
  159.   printf("Number of sectors per track for this disk is %d\n", spt);
  160.   printf("Writing image to drive %c:.  Press ^C to abort.\n", drive+'A');
  161. /*
  162.  * Start writing data to diskette until there is no more data to write.
  163.  */
  164.    head = track = 0;
  165.    while ((count = read(fdin, buffer, buflength)) > 0 && !done) {
  166.      pbuf = buffer;
  167.      for (ns = 1; count > 0 && !done; ns+=3) {
  168.        printf("Track: %02d  Head: %2d Sector: %2d\r", track, head, ns);
  169.        status = biosdisk(WRITE, drive, head, track, ns, 3, pbuf);
  170.  
  171.        if (status != 0) Error(status);
  172.  
  173.        count -= (3*SECTORSIZE);
  174.        pbuf  += (3*SECTORSIZE);
  175.      }
  176.      if ((head = (head + 1) & 1) == 0) ++track;
  177.    }
  178.    if (eof(fdin)) {
  179.      printf("\nDone.\n");
  180.      biosdisk(2, drive, 0, 0, 1, 1, buffer);        /* Retract head    */
  181.    }
  182. }    /* end main */
  183.